# -*- coding: utf-8 -*-
#
# @Time    : 2021/12/1 23:09
# @Author  : 徐良
# File     : baseTableView.py

from typing import List, Union
from PySide6.QtWidgets import QTableView
from PySide6.QtCore import Qt
from baseClass.tools.sysFunction import get_display_resolution


class BaseTableView(QTableView):
    """
    增强型表格视图基类，继承自QTableView

    主要功能增强：
    1. 智能回车键导航（支持行末自动换行）
    2. 表头快捷设置方法
    3. 列显隐状态管理
    4. 自适应屏幕分辨率的列宽设置
    5. 完善的键盘事件处理机制
    """

    def __init__(self, parent=None):
        """
        初始化表格视图

        参数：
            parent: 父级组件，默认为None
        """
        super().__init__(parent)
        # 重写键盘事件处理方法
        self.keyPressEvent = self.table_key_press_event

    def set_header(self, header_labels: List[str]) -> None:
        """
        设置表格水平表头标签

        参数：
            header_labels: 字符串列表，表示各列标题，例如：['序号', '姓名', '年龄']

        异常：
            非字符串元素会自动转换为字符串
        """
        for column, label in enumerate(header_labels):
            self.model().setHeaderData(
                column,
                Qt.Orientation.Horizontal,
                str(label)  # 确保总是字符串类型
            )

    def set_hide_column_by_number(self, column_indices: List[int]) -> None:
        """
        设置隐藏指定列

        参数：
            column_indices: 需要隐藏的列索引列表，例如[0, 2]表示隐藏第1和第3列
        """
        for column in column_indices:
            if isinstance(column, int) and column >= 0:
                self.setColumnHidden(column, True)

    def set_visible_column_by_number(self, visibility_map: List[Union[int, bool]]) -> None:
        """
        根据映射列表设置列可见性

        参数：
            visibility_map: 列的可见性映射列表，
                         1/True表示可见，0/False表示隐藏
        """
        for column, visible in enumerate(visibility_map):
            self.setColumnHidden(column, not bool(visible))

    def set_column_width_by_number(self, width_settings: List[Union[int, float, str]]) -> None:
        """
        智能设置列宽（根据屏幕分辨率自动适配）

        参数：
            width_settings: 列宽设置列表，支持int/float/str类型
        """
        # 分辨率比例映射
        RESOLUTION_RATIOS = {
            3072: 1.0,
            2560: 0.95,
            2048: 0.85,
            1920: 0.8
        }

        screen_width, _ = get_display_resolution()
        ratio = RESOLUTION_RATIOS.get(screen_width, 0.7)

        for column, width in enumerate(width_settings):
            try:
                adjusted_width = max(0, int(float(width) * ratio))
                self.setColumnWidth(column, adjusted_width)
            except (ValueError, TypeError):
                self.setColumnWidth(column, 0)

    def table_key_press_event(self, event):
        """
        处理键盘事件

        参数：
            event: 键盘事件对象
        """
        super().keyPressEvent(event)

        if event.key() in (Qt.Key.Key_Return, Qt.Key.Key_Enter):
            current = self.currentIndex()
            next_index = current.siblingAtColumn(current.column() + 1)

            if not next_index.isValid():
                next_index = current.sibling(current.row() + 1, 0)

            if next_index.isValid():
                self._focus_and_edit_index(next_index)

    def _focus_and_edit_index(self, index):
        """
        聚焦并编辑指定索引单元格

        参数：
            index: 要聚焦的QModelIndex对象
        """
        self.activateWindow()
        self.setFocus()
        self.setCurrentIndex(index)
        self.edit(index)


if __name__ == "__main__":
    from PySide6.QtWidgets import QApplication, QMainWindow
    from PySide6.QtGui import QStandardItemModel, QStandardItem

    app = QApplication([])

    # 测试窗口
    window = QMainWindow()
    window.setWindowTitle("BaseTableView 测试")
    window.resize(800, 600)

    # 创建表格实例
    table = BaseTableView()

    # 设置模型和数据
    model = QStandardItemModel(3, 3)
    for row in range(3):
        for col in range(3):
            item = QStandardItem(f"Row {row + 1} Col {col + 1}")
            model.setItem(row, col, item)
    table.setModel(model)

    # 演示功能
    table.set_header(['ID', 'Name', 'Age'])
    table.set_column_width_by_number([100, 150, '200'])  # 测试字符串输入
    table.set_visible_column_by_number([True, 1, 0])  # 隐藏第三列

    window.setCentralWidget(table)
    window.show()
    app.exec()